package demo2;

/**
 * 数组实现一个循环队列 -- 指向数组头的 front 指向数组尾部的 rear
 * 入队列 rear++, 出队列时 front++
 *
 * 数组实现循环队列的两个问题 :
 *    1. 数组长度有限, 当入队列 rear 到达 k, 就无法继续入队列了
 *                   当出队列 front 到达 k, 就无法继续出队列了, 并且此时数组前面的空间没有释放却得不到利用
 *
 *    2. 如何判断此时是否数组满了, 或者空了
 */
class MyCircularQueue {

    public int[] elem;

    private int front; // 队头

    private int rear; // 队尾

    // 构造方法
    public MyCircularQueue(int capacity) {
        this.elem = new int[capacity];
    }

    /**
     * 入队列
     */
    public boolean enQueue(int value) {
        if(isFull()) {
            return false;
        }

        // 元素没满, 可以继续入队列
        elem[rear] = value;

        // 循环 rear 位置, 防止越界
        rear = (rear + 1) % elem.length;

        return true;
    }

    /**
     * 出队列
     */
    public boolean deQueue() {

        if (isEmpty()) {
            return false;
        }

        front = (front + 1) % elem.length;

        return true;
    }

    /**
     * 获取队头元素
     */
    public int Front() {
        if(isEmpty()) {
            return -1;
        }

        return elem[front];
    }


    /**
     * 获取队尾元素
     */
    public int Rear() {
        if(isEmpty()) {
            return -1;
        }

        return elem[rear == 0 ? elem.length - 1 : rear - 1];
    }
    
    public boolean isEmpty() {
        return front == rear;
    }
    
    public boolean isFull() {
        return (rear + 1) % elem.length == front;
    }
}